package com.diamondfsd.jooq.methods;

import com.diamondfsd.jooq.learn.codegen.tables.records.S1UserRecord;
import com.diamondfsd.jooq.pojo.UserMessagePojo;
import org.jooq.DSLContext;
import org.jooq.Record;
import org.jooq.Record3;
import org.jooq.Result;

import java.time.LocalDateTime;
import java.util.List;

import static com.diamondfsd.jooq.learn.codegen.Tables.S1_USER;
import static com.diamondfsd.jooq.learn.codegen.Tables.S2_USER_MESSAGE;

public class SelectMethod {
  /**
   * 单表查询
   */
  public static void singleSelect(DSLContext dslContext){
    // select `learn-jooq`.`s1_user`.`id`, `learn-jooq`.`s1_user`.`username`, `learn-jooq`.`s1_user`.`email`, `learn-jooq`.`s1_user`.`address`, `learn-jooq`.`s1_user`.`create_time`, `learn-jooq`.`s1_user`.`update_time` from `learn-jooq`.`s1_user`
    Result<Record> fetchResult = dslContext.select().from(S1_USER).fetch();
    List<S1UserRecord> result = fetchResult.into(S1UserRecord.class);

// select `learn-jooq`.`s1_user`.`id`, `learn-jooq`.`s1_user`.`username`, `learn-jooq`.`s1_user`.`email`, `learn-jooq`.`s1_user`.`address`, `learn-jooq`.`s1_user`.`create_time`, `learn-jooq`.`s1_user`.`update_time` from `learn-jooq`.`s1_user` where `learn-jooq`.`s1_user`.`id` in (1, 2)
    Result<Record> fetchAll = dslContext.select().from(S1_USER)
        .where(S1_USER.ID.in(1, 2)).fetch();
    fetchAll.forEach(record -> {
      Integer id = record.getValue(S1_USER.ID);
      String username = record.getValue(S1_USER.USERNAME);
      String address = record.getValue(S1_USER.ADDRESS);
      LocalDateTime createTime = record.getValue(S1_USER.CREATE_TIME);
      LocalDateTime updateTime = record.getValue(S1_USER.UPDATE_TIME);
    });
  }

  /**
   * 关联查询
   * 这里调用的into方法，和selectDemo中的into方法不一样，注意区别
   * 这里的into注入的是自定义实体类，into得到实体的list
   * selectDemo里注入的是表常量，into得到record的list
   * 直接toString也不一样，实体list，记录list，结果Result。
   */
  public static void complexSelect(DSLContext dslContext){
    Result<Record3<String, String, String>> record3Result =
        dslContext.select(S1_USER.USERNAME,
            S2_USER_MESSAGE.MESSAGE_TITLE,
            S2_USER_MESSAGE.MESSAGE_CONTENT)
            .from(S2_USER_MESSAGE)
            .leftJoin(S1_USER).on(S1_USER.ID.eq(S2_USER_MESSAGE.USER_ID))
            .fetch();
    List<UserMessagePojo> userMessagePojoList = record3Result.into(UserMessagePojo.class);
    System.out.println(userMessagePojoList);
  }

  public static void selectDemo(DSLContext dslContext){
    // fetch方法可以返回一个结果集对象 Result
    // jOOQ的Result对象实现了List接口，可以直接当做集合使用
    Result<Record> recordResult = dslContext.select().from(S1_USER).fetch();
    recordResult.forEach(record -> {
      Integer id = record.getValue(S1_USER.ID);
      String username = record.getValue(S1_USER.USERNAME);
      System.out.println("fetch Record     id: " + id + " , username: " + username);
    });

    // 通过 Record.into 方法可以将默认Record对象，转换为表的Record对象，例如S1UserRecord
    // Result 接口也定义了into方法，可以将整个结果集转换为指定表Record的结果集
    // 通过 S1UserRecord 可以通过get方法直接获得表对象
    // 所有表的XXXRecord对象都是实现了 Record 对象的子类
    Result<S1UserRecord> userRecordResult = recordResult.into(S1_USER);
    userRecordResult.forEach(record -> {
      Integer id = record.getId();
      String username = record.getUsername();
      System.out.println("into S1UserRecord   id: " + id + " , username: " + username);
    });

    // fetchInto方法可以可以传入任意class类型，或者表常量
    // 会直接返回任意class类型的List集合，或者指定表Record的结果集对象
    List<S1UserRecord> fetchIntoClassResultList = dslContext.select().from(S1_USER).fetchInto(S1UserRecord.class);
    Result<S1UserRecord> fetchIntoTableResultList = dslContext.select().from(S1_USER).fetchInto(S1_USER);

    System.out.println("fetchIntoClassResultList: \n" + fetchIntoClassResultList.toString());
    System.out.println("fetchIntoTableResultList: \n" + fetchIntoTableResultList.toString());
  }
}
